#include <asm/domain.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
#include <asm/system.h>

#define CONFIG_VECTORS_BASE (0xffff0000)

#include <asm/thread_info.h>
#define modify_domain(dom,type)					\
	do {							\
	struct thread_info *thread = current_thread_info();	\
	unsigned int domain = thread->cpu_domain;		\
	domain &= ~domain_val(dom, DOMAIN_MANAGER);		\
	thread->cpu_domain = domain | domain_val(dom, type);	\
	set_domain(thread->cpu_domain);				\
	} while (0)

void early_trap_init(void)
{
	unsigned long vectors = CONFIG_VECTORS_BASE;
	extern char __stubs_start[], __stubs_end[];
	extern char __vectors_start[], __vectors_end[];
	// extern char __kuser_helper_start[], __kuser_helper_end[];
	// int kuser_sz = __kuser_helper_end - __kuser_helper_start;
	printf("this is %s(): %d\r\n", __func__, __LINE__);

	/*
	 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
	 * into the vector page, mapped at 0xffff0000, and ensure these
	 * are visible to the instruction stream.
	 */
	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
	printf("this is %s(): %d\r\n", __func__, __LINE__);
	memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
	// memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
	printf("this is %s(): %d\r\n", __func__, __LINE__);

	// /*
	//  * Copy signal return handlers into the vector page, and
	//  * set sigreturn to be a pointer to these.
	//  */
	// memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
	//        sizeof(sigreturn_codes));
	// memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
	//        sizeof(syscall_restart_code));

	flush_icache_range(vectors, vectors + PAGE_SIZE);
	printf("this is %s(): %d\r\n", __func__, __LINE__);

	// modify_domain(DOMAIN_USER, DOMAIN_CLIENT);

	printf("this is %s(): %d\r\n", __func__, __LINE__);
}
